package com.tomica.mailsigner.signoffice;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import cfca.mobile.keydevice.AudioToken;

import com.Wsdl2Code.WebServices.SignService.VectorByte;
import com.Wsdl2Code.WebServices.SignService.VectorString;
import com.entersafe.safeca.Constant;
import com.entersafe.safeca.MyProgressDialog;
import com.entersafe.safeca.P11Other;
import com.tomica.mailsigner.R;
import com.tomica.mailsigner.common.SettingsActivity;
import com.tomica.mailsigner.token.Token;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class SignOfficeActivity extends Activity {

	public static final String TAG = "Sign Office";

	public SignOfficeModel mModel;
	public  Context context;
	public  Handler handler;
	public Resources res;

	private Token token;
	private BroadcastReceiver headSetReceiver = null;

	private String randomString;
	public MyProgressDialog progressDialog;

	private String pin;

	@SuppressLint("HandlerLeak")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_sign_office);

		context = this;
		res = getResources();
		P11Other.audioToken = new AudioToken(this);

		progressDialog = new MyProgressDialog(this);

		handler = new Handler(){
			public void handleMessage(Message msg) {
				switch(msg.what) {
				case Constant.GET_SIGNED_OFFICE_OK:
					// Complete sign data. Showing for user:
					progressDialog.dismiss();
					CharSequence text = context.getString(R.string.msg_sign_pdf_successful);
					int duration = Toast.LENGTH_SHORT;
					Toast toast = Toast.makeText(context, text, duration);
					toast.show();

					// TODO : What to do next with that signed file???
					// May save to storage or forward to send a email.
					VectorByte vectorData= (VectorByte) msg.obj;
					byte[] fileData = vectorData.toBytes();

					break;

				case Constant.GET_PASSWORD:
					progressDialog.setShowInfo(getResources().getString(R.string.inform_sign_onprogress));
					progressDialog.show();
					mModel.signOffice(getPdfBase64(), pin);
					break;
				case Constant.WRONG_PASSWORD:
					// Wrong password, user have to re-enter.
					showDialog(Constant.DIALOG_PASSWORD);
					break;
				case Constant.OFFICE_SIGNED_PKCS_OK:
					String signedData = (String) msg.obj;
					mModel.getSignedOfficeFile(randomString, signedData);

					break;	
				case Constant.UP_OFFICE_OK:
					// Call to sign PKCS11
					// Get data from server response:
					//result !=null sẽ có 2 phần tử 
					//result[0]: chứa chuỗi random định danh cho giao dịch
					//result[1]: dữ liệu Server trả về dạng base64,  client cần ký lên dữ liệu này
					VectorString vectorResult = (VectorString) msg.obj;
					randomString = (String) vectorResult.getProperty(0);
					String serverDataBase64 = (String) vectorResult.getProperty(1);

					mModel.signObjectString(serverDataBase64,pin);

					Log.d(TAG, "Upload OFFICE OK");
					break;
				case Constant.SERVICE_EXCEPTION:
					progressDialog.dismiss();
					String message = getResources().getString(R.string.inform_error_internal_server);
					showMessage(message);
					break;
				case Constant.UP_OFFICE_FAIL:
					progressDialog.dismiss();
					break;
				case Constant.GET_SIGNED_OFFICE_FAIL:
					progressDialog.dismiss();

					break;
				case Constant.OFFICE_SIGNED_PKCS_FAIL:
					progressDialog.dismiss();
					break;
				case Constant.SHOWPROGRESSDIALOG:
					Log.e(Constant.Debug, "Dialog of connecting token");
					progressDialog.setShowInfo(res.getString(R.string.inform_tryconnect_init));
					progressDialog.show();
					super.handleMessage(msg);
					break;
				case Constant.CLOSEPROGRESSDIALOG:
					progressDialog.dismiss();
					super.handleMessage(msg);
					break;
				case Constant.SHOWERRINFO:
					if (null != msg.obj) {
						if (msg.obj.toString().compareTo(
								res.getString(R.string.inform_handset_connectfail)) == 0) {
							String title, button;
							button = res.getString(R.string.inform_button_OK);
							title = res.getString(R.string.inform_title);
							new Builder(context)
							.setTitle(title)
							.setMessage(msg.obj.toString())
							.setPositiveButton(button,
									new DialogInterface.OnClickListener() {

								@Override
								public void onClick(
										DialogInterface arg0,
										int arg1) {
									finish();
								}
							}).show();
						} else
							showMessage(msg.obj.toString());
					}
					super.handleMessage(msg);
					break;
				case Constant.TOKEN_CONNECT_OK:
					// Show Toast inform that token connect successfully.
					CharSequence textOK = context.getString(R.string.inform_token_connect_ok);
					Toast toastOk = Toast.makeText(context, textOK, Toast.LENGTH_SHORT);
					toastOk.show();
					break;
				default:
					super.handleMessage(msg);
				}
			}
		};

		mModel = new SignOfficeModel(this, handler);
		token = new Token(context, handler);

		// Register listening to audiopass
		headSetReceiver = new BroadcastReceiver() {
			public void onReceive(Context context, Intent intent) {
				String action = intent.getAction();
				if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
					// headphone plugged
					if (intent.getIntExtra("state", 0) == 1) {
						Log.i("Handset", "Handset plugin");
						token.tryConnect();

						// headphone unplugged
					} else {
						Log.i("Handset", "Handset plugout");
						token.disConnect();
						// TODO: show dialog to insert AudioPass showDialog(0);

					}
				}
			}
		};
		registerReceiver(headSetReceiver, new IntentFilter(
				Intent.ACTION_HEADSET_PLUG));
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.sign_office, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.action_sign:
			if (isOnline()){
				showDialog(Constant.DIALOG_PASSWORD);
			} else {
				// Not online, remind user to check connection
				String message = getResources().getString(R.string.inform_turnon_network);
				showMessage(message);
			}
			return true;
		case R.id.action_settings:
			// Account setting
			Intent intent = new Intent(this, SettingsActivity.class);
			startActivity(intent);
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		Log.i(Constant.Debug, "onDestroy Email sign screen");
		// disConnect();
		P11Other.audioToken.Release();
		unregisterReceiver(headSetReceiver);
	}

	@SuppressWarnings("deprecation")
	@Override
	public Dialog onCreateDialog(int id) {
		switch (id){
		case Constant.DIALOG_PASSWORD:
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			// Get the layout inflater
			LayoutInflater inflater = this.getLayoutInflater();
			View promptView = inflater.inflate(R.layout.dialog_password, null);

			final EditText input = (EditText) promptView.findViewById(R.id.edtInputPass);

			// Inflate and set the layout for the dialog
			// Pass null as the parent view because its going in the dialog layout
			builder.setView(promptView)
			// Add action buttons
			.setPositiveButton(R.string.txt_ok, new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int id) {
					// Continue signing
					pin = input.getText().toString();

					Message msg = new Message();
					msg.what = Constant.GET_PASSWORD;
					handler.sendMessage(msg);
				}
			})
			.setNegativeButton(R.string.txt_cancel, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
					// Do nothing.
				}
			});      
			return builder.create();
		default:
			return super.onCreateDialog(0);
		}
	}

	public byte[] getPdfBase64(){
		Uri uri = getIntent().getData();
		Log.v(TAG,"Uri"+uri.toString());
		ContentResolver resolver = getContentResolver();
		try {
			InputStream input = resolver.openInputStream(uri);
			return mModel.getBytes(input);
			//return IOUtils.toByteArray(input);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public boolean isOnline() {
		ConnectivityManager cm =
				(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netInfo = cm.getActiveNetworkInfo();
		if (netInfo != null && netInfo.isConnectedOrConnecting()) {
			return true;
		}
		return false;
	}

	public static boolean isAvailable(Context ctx, Intent intent) {
		final PackageManager mgr = ctx.getPackageManager();
		List<ResolveInfo> list =
				mgr.queryIntentActivities(intent, 
						PackageManager.MATCH_DEFAULT_ONLY);
		return list.size() > 0;
	}


	private void showMessage(String msg) {
		if (null == msg || "" == msg)
			return;

		String title, button;
		button = getResources().getString(R.string.inform_button_OK);
		title = getResources().getString(R.string.inform_title);
		new Builder(this).setTitle(title).setMessage(msg)
		.setPositiveButton(button, null).show();
	}

}
